package Workflow;

import Constraints.IConstraint;
import Core.ErrorMessage;
import Exceptions.ConstraintErrorException;
import Model.Core.IElement;
import Model.Draw.Events.DrawCompleteListener;
import Model.Draw.Events.ShowTipListener;
import Workflow.States.IState;
import Workflow.Util.IncompatibleStateException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Projeto de TCC: Editor de Diagramas de Comunicação em UML.
 * @author Jose Luz e Michele Puretachi
 * Implementação do IWorkflow. 
 * Consulte a API do IWorkflow para mais informações
 */
public class Workflow implements IWorkflow {

    private IState currentState;
    private IConstraint constraint;

    @Override
    public void setStartUpState(IState startUpState) {
        currentState = startUpState;
    }

    @Override
    public void registerDrawCompleteListener(DrawCompleteListener listener) {
        currentState.registerDrawCompleteListener(listener);
    }

    @Override
    public void registerShowTipsListener(ShowTipListener listener) {
        currentState.registerShowTipsListener(listener);
    }

    @Override
    public void setItem(Object item) throws ConstraintErrorException {
        List<Object> elements = currentState.getItem();
        elements.add(item);
        List<ErrorMessage> errors = constraint.Validate(elements);
        if (errors == null) {
            currentState = currentState.nextState();
            try {
                currentState.setItem(item);
            } catch (IncompatibleStateException ex) {
                Logger.getLogger(Workflow.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            StringBuilder message = new StringBuilder();
            for (ErrorMessage error : errors) {
                message.append(error.getMessage());
            }
            throw new ConstraintErrorException(message.toString());
        }
    }

    @Override
    public boolean sameElement(IElement element) {
        return currentState.getCurrentElement() == null ? false : currentState.getCurrentElement().equals(element);
    }

    @Override
    public void setElement(IElement element) {
        try {
            currentState.setCurrentElement(element);
        } catch (Exception e) {
        }
    }

    @Override
    public void setWorkflowValidation(IConstraint constraint) {
        this.constraint = constraint;
    }
}